package newtank.network.server;

import code.GpcDataServerEncoder;
import code.GpcDecoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import newtank.data.AbstractDataPackage;
import newtank.network.client.handler.RouterClientDataHandler;

/**
 * @author lijiahao
 * @since 2022/1/28
 */
public class ClientNetwork {

    /**
     * 服务主机地址
     */
    private final String host;

    /**
     * 服务端口
     */
    private final int port;

    /**
     * 客户端版本码
     */
    private String md5_client_version;

    private Channel channel;

    private ClientNetwork(String ip, int port) {
        this.host = ip;
        this.port = port;
    }

    public static ClientNetwork builder(String ip, int port) {
        return new ClientNetwork(ip, port);
    }

    public void start() throws InterruptedException {
        final EventLoopGroup group = new NioEventLoopGroup();

        Bootstrap b = new Bootstrap();
        // 使用NioSocketChannel来作为连接用的channel类
        // 绑定连接初始化器
        b.group(group).channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new GpcDataServerEncoder()); //编码request
                        pipeline.addLast(new GpcDecoder()); //解码response
                        pipeline.addLast(new RouterClientDataHandler()); //客户端处理类
                    }
                });
        //发起异步连接请求，绑定连接端口和host信息
        final ChannelFuture future = b.connect(host, port).sync();

        this.channel = future.channel();
    }

    public void sendMessage(AbstractDataPackage message) {
        if(message.getContext() != null) {
            message.setLength(String.valueOf(message.getContext()).getBytes().length);
        }
        channel.writeAndFlush(message);
    }

    public void close() {
        channel.close();
    }

}
